package com.zlq.cn.test;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * AES加密工具类
 *
 * @author xWang
 * @Date 2019-08-27
 */
public class AesEncodeUtil {

    //编码方式
    public static final String CODE_TYPE = "UTF-8";

    //填充类型
    public static final String AES_TYPE = "AES/ECB/PKCS5Padding";
    //public static final String AES_TYPE = "AES/ECB/PKCS7Padding";
    //此类型 加密内容,密钥必须为16字节的倍数位,否则抛异常,需要字节补全再进行加密
    //public static final String AES_TYPE = "AES/ECB/NoPadding";
    //java 不支持ZeroPadding
    //public static final String AES_TYPE = "AES/CBC/ZeroPadding";

    //私钥
    private static final String AES_KEY = "7F3E4A109890FF6A";   //AES固定格式为128/192/256 bits.即：16/24/32bytes。DES固定格式为128bits，即8bytes。


    /**
     * 加密
     *
     * @param cleartext
     * @return
     */
    public static String encrypt(String cleartext) {
        try {
            //两个参数，第一个为私钥字节数组， 第二个为加密方式 AES或者DES
            SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");
            //实例化加密类，参数为加密方式，要写全
            Cipher cipher = Cipher.getInstance(AES_TYPE); //PKCS5Padding比PKCS7Padding效率高，PKCS7Padding可支持IOS加解密
            //初始化，此方法可以采用三种方式，按加密算法要求来添加。（1）无第三个参数（2）第三个参数为SecureRandom random = new SecureRandom();中random对象，随机数。(AES不可采用这种方法)（3）采用此代码中的IVParameterSpec
            //加密时使用:ENCRYPT_MODE;  解密时使用:DECRYPT_MODE;
            cipher.init(Cipher.ENCRYPT_MODE, key); //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
            //加密操作,返回加密后的字节数组，然后需要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器需要什么编码方式
            byte[] encryptedData = cipher.doFinal(cleartext.getBytes(CODE_TYPE));

            return Base64.getEncoder().encodeToString(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解密
     *
     * @param encrypted
     * @return
     */
    public static String decrypt(String encrypted) {
        try {
            byte[] byteMi = Base64.getDecoder().decode(encrypted);
            SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance(AES_TYPE);
            //与加密时不同MODE:Cipher.DECRYPT_MODE
            cipher.init(Cipher.DECRYPT_MODE, key);  //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
            byte[] decryptedData = cipher.doFinal(byteMi);
            return new String(decryptedData, CODE_TYPE);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        String content = "{\"imei\":\"23134654978\",\"isBeingTraced\":\"0\",\"isEmulator\":\"0\",\"isRoot\":\"0\",\"isVirtual\":\"0\",\"isVpn\":\"0\",\"isXposed\":\"0\",\"password\":\"e10adc3949ba59abbe56e057f20f883e\",\"phone\":\"17620410531\"}";
        String enData = encrypt(content);
        System.out.println(enData);
        String deData = decrypt(enData);
        System.out.println(deData);

        content = "c6DUq0xeSW4ynldh2HAoNP6F74AcrmwIFc4ASCeP3HyQxQ3qQqbTY+7n2VWE0XXBZL9IhZsAuCQn+1HY31kSMdw98xINK1lvLjzoQoY7vf52ukA/qkjRfJGHNeT+Yf6yXtvuOcy8E9OGLGURr/XECTWiWM47EbIiNiyvspa+WUXWMEwOMa4QI5z2ELoMfzcz";
        byte[] key2 = "Ap!#SnYoPhwq@J^e".getBytes(StandardCharsets.UTF_8);

        byte[] key1 = "4NUVq$AYwG6vA(D*".getBytes(StandardCharsets.UTF_8);

        // arrayOfByte1, "AES/CBC/PKCS5Padding", arrayOfByte2
        SecretKeySpec secretKeySpec = new SecretKeySpec(key1, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(key2);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decode = Base64.getDecoder().decode(content.getBytes(StandardCharsets.UTF_8));
        byte[] bytes = cipher.doFinal(decode);
    }


}
